package com.risenetsoft.elasticsearch.api;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.filters.Filters;
import org.elasticsearch.search.aggregations.bucket.filters.FiltersAggregator;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.global.GlobalAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.missing.Missing;
import org.elasticsearch.search.aggregations.bucket.nested.Nested;
import org.elasticsearch.search.aggregations.bucket.nested.ReverseNested;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * Created by Zhanggd on 2017/8/9.
 */
public class AggregationBucketDemo {
    public static final String CLUSTER_NAME = "elasticsearch"; //实例名称
    private static final int PORT = 9300;  //端口
    private static final String IP = "192.168.190.104";
    private static Settings settings = Settings.builder()
            .put("cluster.name",CLUSTER_NAME)
            .put("client.transport.sniff",true)
            .put("client.transport.ping_timeout","120s")
            .build();

    private static TransportClient client;
    static {
        try {
            client = new PreBuiltTransportClient(settings)
                    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(IP), PORT));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    public static void global(){
        GlobalAggregationBuilder aggregation = AggregationBuilders.global("global")
                .subAggregation(AggregationBuilders.terms("genders").field("gender"));

        SearchResponse searchResponse = client.prepareSearch("user")
                .addAggregation(aggregation).get();

        Global global = searchResponse.getAggregations().get("global");
        long docCount = global.getDocCount();
        System.out.println(docCount);
    }

    public static void filter(){
        FilterAggregationBuilder aggregation = AggregationBuilders.filter("filter",
                QueryBuilders.termQuery("gender","female"));

        SearchResponse searchResponse = client.prepareSearch("user")
                .addAggregation(aggregation).get();
        Filter filter = searchResponse.getAggregations().get("filter");
        long docCount = filter.getDocCount();
        System.out.println(docCount);
    }

    public static void filters(){
        AggregationBuilder aggregation = AggregationBuilders.filters("filters"
        ,new FiltersAggregator.KeyedFilter("men",QueryBuilders.termQuery("gender","male"))
        ,new FiltersAggregator.KeyedFilter("women",QueryBuilders.termQuery("gender","female")));

        SearchResponse searchResponse = client.prepareSearch("user")
                .addAggregation(aggregation).get();

        Filters filters = searchResponse.getAggregations().get("filters");
        for (Filters.Bucket entry:filters.getBuckets()){
            String key = entry.getKeyAsString();
            long docCount = entry.getDocCount();
            System.out.println("key ["+key+"] , docCount ["+docCount+"]");
        }
    }

    public static void missing(){
        AggregationBuilder aggregation = AggregationBuilders.missing("agg").field("gender");
        SearchResponse searchResponse = client.prepareSearch("user")
                .addAggregation(aggregation).get();

        Missing agg = searchResponse.getAggregations().get("agg");
        long docCount = agg.getDocCount();
        System.out.println(docCount);
    }

    public static void nested(){
        AggregationBuilder aggregation = AggregationBuilders
                .nested("agg", "resellers");

        SearchResponse searchResponse = client.prepareSearch("user")
                .addAggregation(aggregation).get();

        Nested agg = searchResponse.getAggregations().get("agg");
        long docCount = agg.getDocCount();
        System.out.println(docCount);
    }

    public static void reverseNested(){
        AggregationBuilder aggregation = AggregationBuilders.nested("agg", "resellers")
                .subAggregation(AggregationBuilders.terms("name").field("resellers.name")
                .subAggregation(AggregationBuilders.reverseNested("product_id")));
        SearchResponse searchResponse = client.prepareSearch("user")
                .addAggregation(aggregation).get();

        Nested agg = searchResponse.getAggregations().get("agg");
        Terms name = agg.getAggregations().get("name");
        for (Terms.Bucket bucket : name.getBuckets()) {
            ReverseNested resellerToProduct = bucket.getAggregations().get("reseller_to_product");
            resellerToProduct.getDocCount(); // Doc count
        }
    }

    public static void main(String[] args) {
        //global();

        filter();

        filters();

        //missing();

        //nested();

        //reverseNested();


    }



}
